import { _decorator, Component, error, instantiate, Node, NodePool, Prefab } from 'cc';
import Singleton from './Singleton';
import { ResMgr } from '../Res/ResMgr';
const { ccclass, property } = _decorator;

export class PoolMgr extends Singleton<PoolMgr>() {
    //用于存储对象池，对象池的管理
    private _nodePoolMap: Map<string, Pool> = new Map();
    //获取对象池
    getNodePool(nodePoolName: string) {
        if (nodePoolName.length <= 0 || !nodePoolName) {
            console.error("对象池名字有误");
            return;
        }
        let nodePool = this._nodePoolMap.get(nodePoolName);
        if (!nodePool) {
            nodePool = new Pool(10, nodePoolName);
            //将对象池存入容器中
            this.addNodePool(nodePoolName, nodePool);
        }
        return nodePool;
    }

    //存储对象池
    addNodePool(nodePoolName: string, nodePool: Pool) {
        if (nodePoolName.length <= 0 || !nodePoolName) {
            console.error("对象池名字有误");
            return;
        }
        this._nodePoolMap.set(nodePoolName, nodePool);
    }

    //删除对象池
    deleteNodePool(nodePoolName: string) {
        if (nodePoolName.length <= 0 || !nodePoolName) {
            console.error("对象池名字有误");
            return;
        }
        if (!this._nodePoolMap.has(nodePoolName)) {
            console.error(nodePoolName + "对象池不存在");
            return;
        }
        this._nodePoolMap.delete(nodePoolName);
    }
}

export class Pool {
    private _initSize: number = null;
    private _nodePool: NodePool = null;
    private _prefab: Prefab = null;
    constructor(initSize: number, nodeName: string) {
        this._initSize = initSize;
        this.initNodePool(nodeName);
    }

    initNodePool(nodeName: string) {
        this._prefab = ResMgr.instance.getRes<Prefab>("Game", nodeName);
        if (!this._prefab) {
            console.error(nodeName + "资源未加载");
            return;
        }
        this._nodePool = new NodePool();
        for (let i = 0; i < this._initSize; i++) {
            let node = instantiate(this._prefab);
            this._nodePool.put(node);
        }
    }
    //获取节点
    getNode(): Node {
        let node = null;
        //对象池中的节点不够时
        if (this._nodePool.size() <= 0) {
            node = instantiate(this._prefab);
            return node;
        }
        node = this._nodePool.get();
        return node;
    }

    //回收节点
    destroyNode(node: Node) {
        //判断对象池是否已满,已满直接销毁节点
        if (this._nodePool.size() >= this._initSize) {
            node.destroy();
            return;
        }
        this._nodePool.put(node);
    }
}
